﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Com.OpenCode.Framework.Core;
using log4net;
using log4net.Config;

namespace Com.OpenCode.Framework.Log
{
    public class LogCollectionServices
    {
        #region 静态构造函数

        public static void Init(string path)
        {
            LogServices.ListenLog += LogServices_ListenLog;
            string info = CreateLogConfig(Path.Combine(path, "Log\\log.log"));
            FileStream fileStream = File.Create(Path.Combine(path, "log4net.xml"));
            StreamWriter streamWrite = new StreamWriter(fileStream);
            streamWrite.Write(info);
            streamWrite.Close();
            XmlConfigurator.Configure(new FileInfo(Path.Combine(path, "log4net.xml")));
            File.Delete(Path.Combine(path, "log4net.xml"));
        }

        #endregion

        private static string CreateLogConfig(string logPath)
        {
            StringBuilder stringBuilder = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            stringBuilder.AppendLine("<log4net xmlns=\"urn:log4net\">");
            stringBuilder.AppendLine("<root>");
            stringBuilder.AppendLine("<level value=\"INFO\" />");
            stringBuilder.AppendLine("<appender-ref ref=\"RollingFileAppender\" />");
            stringBuilder.AppendLine("</root>");
            stringBuilder.AppendLine("<appender name=\"RollingFileAppender\" type=\"log4net.Appender.RollingFileAppender\">");
            stringBuilder.AppendLine("<file value=\"" + logPath + "\" />");
            stringBuilder.AppendLine("<lockingModel type=\"log4net.Appender.FileAppender+MinimalLock\" />");
            stringBuilder.AppendLine("<datePattern value=\"'_'yyyyMMdd\" />");
            stringBuilder.AppendLine("<staticLogFileName value=\"true\" />");
            stringBuilder.AppendLine("<appendToFile value=\"true\" />");
            stringBuilder.AppendLine("<rollingStyle value=\"Composite\" />");
            stringBuilder.AppendLine("<maxSizeRollBackups value=\"10\" />");
            stringBuilder.AppendLine("<maximumFileSize value=\"5MB\" />");
            stringBuilder.AppendLine(" <layout type=\"log4net.Layout.PatternLayout\">");
            stringBuilder.AppendLine("<conversionPattern value=\"时间：%date%newline类别：%logger%newline级别：%level%newline消息：%message%newline异常：%exception%newline%newline\" />");
            stringBuilder.AppendLine("</layout>");
            stringBuilder.AppendLine("</appender>");
            stringBuilder.AppendLine("</log4net>");
            return stringBuilder.ToString();
        }

        /// <summary>
        ///     获取日志信息。
        /// </summary>
        public static List<LogRecord> Get()
        {
            string _LogFilePath = "";
            List<LogRecord> records = new List<LogRecord>();
            FileStream fileStream = new FileStream(_LogFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            StreamReader reader = new StreamReader(fileStream, Encoding.Default);
            string loginfo = reader.ReadToEnd();
            reader.Close();
            fileStream.Close();
            MatchCollection matches = Regex.Matches(loginfo,
                @"(?<data>[0-9]{4}-[0-9]{2}-[0-9]{2})\s(?<time>[0-9]{2}:[0-9]{2}:[0-9]{2})\,[0-9]{3}[\s\S]{5}(?<assym>[\s\S]*?\n)[\s\S]{3}(?<type>[\s\S]*?\n)[\s\S]{3}(?<info>[\s\S]*?\n)[\s\S]{3}");
            foreach (Match match in matches)
            {
                string data = match.Groups["data"].Value.Trim();
                string time = match.Groups["time"].Value.Trim();
                string assym = match.Groups["assym"].Value.Trim();
                string type = match.Groups["type"].Value.Trim();
                string info = match.Groups["info"].Value.Trim();
                LogType logType = LogType.Info;
                if (type == "WARN")
                {
                    logType = LogType.Warn;
                }
                else if (type == "ERROR")
                {
                    logType = LogType.Error;
                }
                DateTime dateTime;
                DateTime.TryParse(data + " " + time, out dateTime);
                records.Add(new LogRecord {Info = info, Type = logType, DateTime = dateTime});
            }
            return records;
        }

        private static void LogServices_ListenLog(LogEventArgs e)
        {
            ILog _Log = null;
            if (e.Type == null)
            {
                _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
            }
            else
            {
                _Log = LogManager.GetLogger(e.Type);
            }
            if (e.LogRecord.Type == LogType.Error)
            {
                _Log.Error(e.LogRecord.Info);
                if (e.Show)
                {
                    OpenCodeAlertControlHelper.ShowError("错误", e.LogRecord.Info);
                }
            }
            else if (e.LogRecord.Type == LogType.Info)
            {
                _Log.Info(e.LogRecord.Info);
                if (e.Show)
                {
                    OpenCodeAlertControlHelper.ShowInfo("信息", e.LogRecord.Info);
                }
            }
            else if (e.LogRecord.Type == LogType.Warn)
            {
                _Log.Warn(e.LogRecord.Info);
                if (e.Show)
                {
                    OpenCodeAlertControlHelper.ShowWaring("警告", e.LogRecord.Info);
                }
            }
        }
    }
}